//==================================================================
//  Copyright (C) 2006  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
//==
//==
//==
//==================================================================

#include "stdafx.h"
#include "m5d_utils_ext.h"

using namespace PMath;

//==================================================================
namespace M5D {

//==================================================================
Vector3 UnProject( const Vector3 &win, const Matrix44 &model_m, const Matrix44 &proj_m, const int vport[4] )
{
	Vector4 omog(	((win._x - vport[0]) / vport[2]) * 2 - 1,
					((win._y - vport[1]) / vport[3]) * 2 - 1,
					 (win._z					   ) * 2 - 1,
					1 );

	//Vector4 outv = model_m.GetBackTransformed() * proj_m.GetBackProjected() * omog;
	Vector4 outv = (proj_m * model_m).GetInverse() * omog;
	outv *= 1 / outv._w;
	return Vector3( outv._x, outv._y, outv._z );
}

//==================================================================
void GetHRayFromWinPos( int in_x, int in_y,
					    const int viewport[4],
					    const Matrix44 &modelview_m,
						const Matrix44 &project_m,
						Vector3 &ray_from, Vector3 &ray_dir )
{
	float winX = (float)in_x;
	float winY = (float)viewport[3]-1 - in_y;

	ray_from = UnProject( Vector3(winX, winY, 0), modelview_m, project_m, viewport );
	ray_dir  = UnProject( Vector3(winX, winY, 1), modelview_m, project_m, viewport ) - ray_from;
}

//==================================================================
void TransArray( u_char *data, u_char *temp, int item_size, const int *tablep, int nv )
{
	memcpy( temp, data, nv * item_size );
	for (int i=0; i < nv; ++i)
		memcpy( data + tablep[i] * item_size,
				temp +		   i * item_size,
				item_size );
}

};
